package cn.tedu._04mvcweibo.reflect;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
//Knife4j底层的实现逻辑?(有注解吗?谁来解析哪些注解呢?)

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface ApiOperation{
    String value() default "";
}
//可以在ApiOperation的类文件所在类文件目录中执行javap -v ApiOperation.class

class XxxController{
    @ApiOperation(value = "获取消息")
    void doMsg(){
    }
}
@SpringBootTest
public class ReflectDemo01 {
    //在这里获取XxxController中doMsg方法上@ApiOperation中value方法的值.
     @Test
     void testReflect01() throws NoSuchMethodException {
        //1.获取XxxController的字节码对象
         Class<XxxController> cls = XxxController.class;
         //2.获取doMsg方法对象
         Method doMsg =
                 cls.getDeclaredMethod("doMsg");
         //3.获取doMsg方法对象上的ApiOperation注解
         ApiOperation annotation =
                 doMsg.getAnnotation(ApiOperation.class);
         //4.获取ApiOperation注解中的value方法值
         String value = annotation.value();
         System.out.println(value);
     }

     //通过反射技术演示方法的调用,同时掌握何为泛型类型擦除.
     //思考:SpringMVC中Controller方法的调用过程
     @Test
     void testReflect() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
         ArrayList<String> list=new ArrayList<String>();
         //list.add(100);//error
         //1.获取ArrayList字节码对象
         Class<?> aClass = list.getClass();
         //2.获取add方法对象
         Method addMethod = aClass.getDeclaredMethod("add", Object.class);
         //3.调用add方法对象,将100放入到集合
         Object result = addMethod.invoke(list, 100);
         //4.输出list结果
         System.out.println(result);
         System.out.println(list);
     }//11:10
}
